package edu.tamu.cse.teamproject1;

import java.util.Date;

/**
 * Provides methods for comparing values based on SQL Queries
 * 
 * This class has a very specific purpose for providing comparason operations
 * on values retrieved from TupleElements and values obtained from a query string
 * passed to a Filter. Because it is impossible to cast and do an in-line comparison
 * with a string, this class will provide the necessary methods to provide the
 * equivalent comparisons. 
 * 
 * @author Christopher Weldon <chris@chrisweldon.net>
 */
public class ComparatorParser {
	/**
	 * Retrieves the comparison enum type based on a comparison string
	 * 
	 * @param comparison Comparison to occur (must be either <, <=, =, >, >=, !=
	 * @return Comparator Enum value
	 * @throws IllegalArgumentException when an invalid comparator is passed
	 */
	public static EnumComparator fetchComparisonType(String comparison)
		throws IllegalArgumentException {
		if (comparison == null || comparison.equals("")) {
			throw new IllegalArgumentException("comparison operator is invalid.");
		}
		EnumComparator comparator = null;
		if (comparison.equals("<")) {
			comparator = EnumComparator.LESS_THAN;
		} else if (comparison.equals("<=")) {
			comparator = EnumComparator.LESS_THAN_OR_EQUALS;
		} else if (comparison.equals("=")) {
			comparator = EnumComparator.EQUALS;
		} else if (comparison.equals(">")) {
			comparator = EnumComparator.GREATER_THAN;
		} else if (comparison.equals(">=")) {
			comparator = EnumComparator.GREATER_THAN_OR_EQUALS;
		} else if (comparison.equals("!=")) {
			comparator = EnumComparator.NOT_EQUALS;
		} else {
			throw new IllegalArgumentException("comparison operator is not a valid operator.");
		}
		
		return comparator;
	}
	
	/**
	 * Compares integer values against a comparator
	 * 
	 * value1 is always on the left side of the comparator and value2 is always
	 * on the right side of the comparator.
	 * 
	 * @param value1
	 * @param value2
	 * @param comparator
	 * @return Do the values adhere to the comparator?
	 * @throws IllegalArgumentException
	 */
	public static boolean compare(int value1, int value2, String comparator) 
		throws IllegalArgumentException {
		// Assume false
		boolean doesAdhere = false;
		
		// Make the comparison and return
		switch (ComparatorParser.fetchComparisonType(comparator)) {
		case LESS_THAN:
			doesAdhere = (value1 < value2);
			break;
		case LESS_THAN_OR_EQUALS:
			doesAdhere = (value1 <= value2);
			break;
		case EQUALS:
			doesAdhere = (value1 == value2);
			break;
		case GREATER_THAN:
			doesAdhere = (value1 > value2);
			break;
		case GREATER_THAN_OR_EQUALS:
			doesAdhere = (value1 >= value2);
			break;
		case NOT_EQUALS:
			doesAdhere = (value1 != value2);
			break;
		default:
			throw new IllegalArgumentException("comparator is invalid.");
		}
		
		return doesAdhere;
	}
	
	/**
	 * Compares floating point values to a comparator
	 * 
	 * value1 is always on the left side of the comparator and value2 is always
	 * on the right side of the comparator.
	 * 
	 * @param value1
	 * @param value2
	 * @param comparator
	 * @return Do the values adhere to the comparator?
	 * @throws IllegalArgumentException
	 */
	public static boolean compare(float value1, float value2, String comparator) 
		throws IllegalArgumentException {
		// Assume false
		boolean doesAdhere = false;
		
		// Make the comparison and return
		switch (ComparatorParser.fetchComparisonType(comparator)) {
		case LESS_THAN:
			doesAdhere = (value1 < value2);
			break;
		case LESS_THAN_OR_EQUALS:
			doesAdhere = (value1 <= value2);
			break;
		case EQUALS:
			doesAdhere = (value1 == value2);
			break;
		case GREATER_THAN:
			doesAdhere = (value1 > value2);
			break;
		case GREATER_THAN_OR_EQUALS:
			doesAdhere = (value1 >= value2);
			break;
		case NOT_EQUALS:
			doesAdhere = (value1 != value2);
			break;
		default:
			throw new IllegalArgumentException("comparator is invalid.");
		}
		
		return doesAdhere;
	}
	
	/**
	 * Compares string values against a comparator
	 * 
	 * value1 is always on the left side of the comparator, while value2 is always
	 * on the right side of the comparator.
	 * 
	 * Because strings can only be compared using == and !=, if any other comparator
	 * is specified, an IllegalArgumentException will be thrown. 
	 * 
	 * @param value1
	 * @param value2
	 * @param comparator
	 * @return Do the values adhere to the comparator?
	 * @throws IllegalArgumentException
	 */
	public static boolean compare(String value1, String value2, String comparator) 
		throws IllegalArgumentException {
		// Assume false
		boolean doesAdhere = false;
		
		// Make the comparison and return
		switch (ComparatorParser.fetchComparisonType(comparator)) {
		case EQUALS:
			doesAdhere = (value1 == value2);
			break;
		case NOT_EQUALS:
			doesAdhere = (value1 != value2);
			break;
		case LESS_THAN:
		case LESS_THAN_OR_EQUALS:
		case GREATER_THAN:
		case GREATER_THAN_OR_EQUALS:
		default:
			throw new IllegalArgumentException("comparator is invalid.");
		}
		
		return doesAdhere;
	}
	
	/**
	 * Compares dates against a comparator
	 * 
	 * Dates can be numerically compared, as opposed to strings. value1 is always
	 * on the left side of the comparator while value2 is always on the right side
	 * of the comparator.
	 * 
	 * @param value1
	 * @param value2
	 * @param comparator
	 * @return
	 * @throws IllegalArgumentException
	 */
	public static boolean compare(Date value1, Date value2, String comparator) 
		throws IllegalArgumentException {
		// Assume false
		boolean doesAdhere = false;
		
		// Make the comparison and return
		switch (ComparatorParser.fetchComparisonType(comparator)) {
		case LESS_THAN:
			doesAdhere = (value1.compareTo(value2) < 0);
			break;
		case LESS_THAN_OR_EQUALS:
			doesAdhere = (value1.compareTo(value2) <= 0);
			break;
		case EQUALS:
			doesAdhere = (value1.compareTo(value2) == 0);
			break;
		case GREATER_THAN:
			doesAdhere = (value1.compareTo(value2) > 0);
			break;
		case GREATER_THAN_OR_EQUALS:
			doesAdhere = (value1.compareTo(value2) >= 0);
			break;
		case NOT_EQUALS:
			doesAdhere = (value1.compareTo(value2) != 0);
			break;
		default:
			throw new IllegalArgumentException("comparator is invalid.");
		}
		
		return doesAdhere;
	}
}
